package com.smart.community.region.service.impl;

import java.util.List;
import java.util.Arrays;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.enums.SystemStatusEnum;
import com.smart.community.commons.exception.BusinessException;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.feign.property.service.DataScopeFeign;
import com.smart.community.feign.user.dto.UserDTO;
import com.smart.community.feign.user.service.UserFeignService;
import com.smart.community.region.dto.ResidentAddDTO;
import com.smart.community.region.entity.Household;
import com.smart.community.region.entity.Resident;
import com.smart.community.region.entity.ResidentHousehold;
import com.smart.community.region.mapper.HouseholdMapper;
import com.smart.community.region.mapper.ResidentHouseholdMapper;
import com.smart.community.region.mapper.ResidentMapper;
import com.smart.community.region.service.IResidentService;
import com.smart.community.feign.user.dto.NormalUserCreateDTO;

import lombok.extern.slf4j.Slf4j;

/**
 * 住户信息服务实现类
 * 
 * @author Wu.Liang
 * @since 2025-07-28
 */
@Service
@Slf4j
public class ResidentServiceImpl extends ServiceImpl<ResidentMapper, Resident> implements IResidentService {
	@Autowired
    private HouseholdMapper householdMapper;
    @Autowired
    private ResidentHouseholdMapper residentHouseholdMapper;
    @Autowired
    private UserFeignService userFeignService;
    @Autowired
    private DataScopeFeign dataScopeFeign;
    
    @Override
    public List<Resident> getResidentsByUserId(Long userId) throws Exception {
        log.info("根据用户ID查询住户信息，用户ID：{}", userId);
        
        return baseMapper.selectByUserId(userId);
    }
    
    @Override
    public List<Resident> getResidentsByRealName(String realName) throws Exception {
        log.info("根据姓名模糊查询住户，姓名：{}", realName);
        
        return baseMapper.selectByRealName(realName);
    }
    
    @Override
    public Resident addResidentWithPermission(ResidentAddDTO residentAddDTO) throws Exception {
        log.info("新增住户信息（带权限验证），住户姓名：{}", residentAddDTO.getRealName());
        
        // 1. 参数校验
        validateAddResidentParams(residentAddDTO);
        
        // 2. 权限验证
        validateAddResidentPermission(residentAddDTO.getHouseholdId());
        
        // 3. 创建住户实体
        Resident resident = new Resident();
        BeanUtils.copyProperties(residentAddDTO, resident);
        
        // 4. 设置创建信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId != null) {
            resident.setCreateBy(currentUserId);
            resident.setUpdateBy(currentUserId);
        }
        
        // 5. 处理用户关联逻辑
        Long associatedUserId = handleUserAssociation(residentAddDTO);
        if (associatedUserId != null) {
        	resident.setUserId(associatedUserId);
        }
        
        // 6. 保存住户信息 
        boolean result = this.save(resident);
        if (!result) {
            throw new BusinessException("新增住户信息失败");
        }
        
        log.info("新增住户信息成功，住户ID：{}，关联用户ID：{}", resident.getId(), associatedUserId);
        
        // 7. 创建住户房户关联信息
        createResidentHouseholdAssociation(resident.getId(), residentAddDTO, currentUserId);
        
        return resident;
    }
    
    /**
     * 参数校验
     */
    private void validateAddResidentParams(ResidentAddDTO residentAddDTO) throws Exception {
        if (residentAddDTO.getRealName() == null || residentAddDTO.getRealName().trim().isEmpty()) {
            throw new BusinessException("住户姓名不能为空");
        }
        if (residentAddDTO.getIdentityNo() == null || residentAddDTO.getIdentityNo().trim().isEmpty()) {
            throw new BusinessException("身份证件号不能为空");
        }
        if (residentAddDTO.getHouseholdId() == null) {
            throw new BusinessException("房户ID不能为空");
        }
    }
    
    /**
     * 权限验证
     */
    private void validateAddResidentPermission(Long householdId) throws Exception {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        // 用户有权限管理的社区ID集合
        List<Long> userCommunityIds = dataScopeFeign.getUserCommunityIds(currentUserId);
        
        // 1. 检查超级管理员权限
        Boolean isSuperAdmin = dataScopeFeign.isUserSuperAdmin(currentUserId);
        if (isSuperAdmin) {
            log.info("超级管理员新增住户，跳过权限验证");
            return;
        }
        
        // 2. 获取房户信息，验证用户是否有权限在该房户添加住户
        // 这里需要根据房户ID获取社区ID，然后验证用户是否有该社区的权限
        Household household = householdMapper.selectById(householdId);
        // 由于区域服务没有提供房户详情查询的Feign接口，这里暂时跳过社区权限验证
        if (household != null && userCommunityIds.contains(household.getCommunityId())) {
        	return;
        } else {
        	log.error("当前用户[id={}]无权限进行此房户的操作", currentUserId);
        	throw new BusinessException("创建新用户失败");
        }
        // TODO: 后续需要完善房户详情查询接口，实现完整的权限验证
    }
    
    /**
     * 处理用户关联逻辑
     */
    private Long handleUserAssociation(ResidentAddDTO residentAddDTO) throws Exception {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        
        // 1. 尝试根据手机号查找用户
        if (residentAddDTO.getPhone() != null && !residentAddDTO.getPhone().trim().isEmpty()) {
            try {
                UserDTO userDTO = userFeignService.getUserByPhone(residentAddDTO.getPhone());
                if (userDTO != null) {
                    log.info("根据手机号找到关联用户，用户ID：{}", userDTO.getId());
                    return userDTO.getId();
                }
            } catch (Exception e) {
                log.warn("根据手机号查找用户失败，手机号：{}，错误：{}", residentAddDTO.getPhone(), e.getMessage());
            }
        }
        
        // 2. 如果根据手机号没找到，尝试根据身份证号查找用户
        if (residentAddDTO.getIdentityNo() != null && !residentAddDTO.getIdentityNo().trim().isEmpty()) {
            try {
                UserDTO userDTO = userFeignService.getUserByIdCard(residentAddDTO.getIdentityNo());
                if (userDTO != null) {
                    log.info("根据身份证号找到关联用户，用户ID：{}", userDTO.getId());
                    return userDTO.getId();
                }
            } catch (Exception e) {
                log.warn("根据身份证号查找用户失败，身份证号：{}，错误：{}", residentAddDTO.getIdentityNo(), e.getMessage());
            }
        }
        
        // 3. 如果都没找到，创建新用户
        if ((residentAddDTO.getPhone() != null && !residentAddDTO.getPhone().trim().isEmpty()) ||
            (residentAddDTO.getIdentityNo() != null && !residentAddDTO.getIdentityNo().trim().isEmpty())) {
            
            try {
                log.info("未找到关联用户，开始创建新用户，姓名：{}，手机号：{}，身份证号：{}", 
                    residentAddDTO.getRealName(), residentAddDTO.getPhone(), residentAddDTO.getIdentityNo());
                
                // 创建NormalUserCreateDTO
                NormalUserCreateDTO createDTO = new NormalUserCreateDTO();
                createDTO.setRealName(residentAddDTO.getRealName());
                createDTO.setPhone(residentAddDTO.getPhone());
                createDTO.setIdCard(residentAddDTO.getIdentityNo());
                createDTO.setGender(residentAddDTO.getGender());
                
                // 设置用户名（优先使用手机号，其次使用身份证号）
                if (residentAddDTO.getPhone() != null && !residentAddDTO.getPhone().trim().isEmpty()) {
                    createDTO.setUsername(residentAddDTO.getPhone());
                } else if (residentAddDTO.getIdentityNo() != null && !residentAddDTO.getIdentityNo().trim().isEmpty()) {
                    createDTO.setUsername(residentAddDTO.getIdentityNo());
                } else {
                    // 如果都没有，使用姓名+时间戳
                    createDTO.setUsername(residentAddDTO.getRealName() + System.currentTimeMillis());
                }
                
                // 设置操作人ID（Feign接口规范要求显式传入）
                createDTO.setOperatorId(currentUserId);
                
                // 创建用户
                Long newUserId = userFeignService.createNormalUser(createDTO);
                if (newUserId != null) {
                    log.info("新用户创建成功，用户ID：{}", newUserId);
                    
                    // 4. 给新用户分配普通用户角色（ID=13）
                    try {
                        List<Long> roleIds = Arrays.asList(13L);
                        userFeignService.assignUserRoles(newUserId, roleIds);
                        log.info("已为新用户分配普通用户角色，用户ID：{}", newUserId);
                    } catch (Exception roleException) {
                        log.warn("分配普通用户角色失败，用户ID：{}，错误：{}", newUserId, roleException.getMessage());
                        // 不抛出异常，避免影响主流程
                    }
                    
                    return newUserId;
                } else {
                    log.warn("新用户创建失败，姓名：{}，手机号：{}", residentAddDTO.getRealName(), residentAddDTO.getPhone());
                }
            } catch (Exception createException) {
                log.error("创建新用户失败，姓名：{}，手机号：{}，身份证号：{}，错误：{}", 
                    residentAddDTO.getRealName(), residentAddDTO.getPhone(), residentAddDTO.getIdentityNo(), 
                    createException.getMessage(), createException);
                // 不抛出异常，避免影响主流程
            }
        }
        
        // 如果没有找到关联用户且创建失败，返回null
        log.info("未找到关联用户且创建新用户失败，住户将不关联用户账号");
        return null;
    }
    
    /**
     * 创建住户房户关联信息
     */
    private void createResidentHouseholdAssociation(Long residentId, ResidentAddDTO residentAddDTO, Long currentUserId) throws Exception {
        ResidentHousehold residentHousehold = new ResidentHousehold();
        residentHousehold.setResidentId(residentId);
        residentHousehold.setHouseholdId(residentAddDTO.getHouseholdId());
        residentHousehold.setResidentType(residentAddDTO.getResidentType() != null ? residentAddDTO.getResidentType() : 1); // 默认为户主
        residentHousehold.setMoveInDate(residentAddDTO.getMoveInDate());
        residentHousehold.setMoveOutDate(residentAddDTO.getMoveOutDate());
        residentHousehold.setContractStartDate(residentAddDTO.getContractStartDate());
        residentHousehold.setContractEndDate(residentAddDTO.getContractEndDate());
        residentHousehold.setMonthlyRent(residentAddDTO.getMonthlyRent());
        residentHousehold.setDeposit(residentAddDTO.getDeposit());
        residentHousehold.setContractNo(residentAddDTO.getContractNo());
        residentHousehold.setApplyStatus(SystemStatusEnum.ENABLED.getCode()); // 默认已通过
        residentHousehold.setStatus(SystemStatusEnum.ENABLED.getCode()); // 默认有效
        
        // 设置创建信息
        if (currentUserId != null) {
            residentHousehold.setCreateBy(currentUserId);
            residentHousehold.setUpdateBy(currentUserId);
        }
        
        // 保存住户房户关联信息
        boolean associationResult = residentHouseholdMapper.insert(residentHousehold) > 0;
        if (!associationResult) {
            throw new BusinessException("创建住户房户关联信息失败");
        }
        
        log.info("创建住户房户关联信息成功，关联ID：{}", residentHousehold.getId());
    }
} 